#include <stdio.h>

#define MAX_n 20

#define MAX_m 500

struct _GridPaper {

int n;

int m;

int array[MAX_n][MAX_m];

};

typedef struct _GridPaper GridPaper;

int symmetry(int pos, int foldpos) {

int t;

t = 2 * foldpos - pos - 1;

return t < pos ? t : pos;

}

int fold(const GridPaper *origin, int x, int y, GridPaper *borne) {

int mx;

int i, j;

int M, N, k;

N = origin->n;

M = origin->m;

mx = origin->array[0][0];

for (i = 0; i < N; i++) {

for (j = 0; j < M; j++) {

borne->array[i][j] = 0;

}

}

if (x < 1) {

borne->n = origin->n;

borne->m = y < origin->m - y ? y : origin->m - y;

for (j = 0; j < M; j++) {

k = symmetry(j, y);

for (i = 0; i < N; i++) {

borne->array[i][k] += origin->array[i][j];

}

}

} else {

borne->n = x < origin->n - x ? x : origin->n - x;

borne->m = origin->m;

for (i = 0; i < N; i++) {

k = symmetry(i, x);

for (j = 0; j < M; j++) {

borne->array[k][j] += origin->array[i][j];

}

}

}

for (i = 0; i < N; i++) {

for (j = 0; j < M; j++) {

if (mx < borne->array[i][j]) {

mx = borne->array[i][j];

}

}

}

return mx;

}

int mxgd(GridPaper *gp) {

int mx, i, big;

GridPaper xgp;

mx = gp->array[0][0];

if (gp->m == 1 && gp->n == 1)

return mx;

for (i = 1; i < gp->n; i++) {

big = fold(gp, i, -1, &xgp);

if (big > mx)

mx = big;

big = mxgd(&xgp);

if (big > mx)

mx = big;

}

for (i = 1; i < gp->m; i++) {

big = fold(gp, -1, i, &xgp);

if (big > mx)

mx = big;

big = mxgd(&xgp);

if (big > mx)

mx = big;

}

return mx;

}

int main() {

int N, M;

int i, j;

int maxGrid;

GridPaper gp;

scanf("%d %d", &N, &M);

gp.n = N;

gp.m = M;

for (i = 0; i < N; i++) { 

for (j = 0; j < M; j++) {

scanf("%d", &gp.array[i][j]);

}

}

maxGrid = mxgd(&gp);

printf("%d\n", maxGrid);

return 0;

}
